<template>
  <div class="widget-config">
    <el-form
      label-suffix=":" v-if="localData && Object.keys(localData).length > 0" labelPosition="right"
      labelWidth="100px" size="default">
      <el-collapse v-model="collapse">
        <el-collapse-item name="1" title="基本属性">
          <el-form-item label="组件标识">
            <el-input v-model="localData.uuid" placeholder="自动生成" disabled />
          </el-form-item>
          <el-form-item label="组件类型" v-if="localData.type && !localData.component">
            <el-select
              v-model="localData.type" disabled style="width: 100%" placeholder="请选择类型"
              @change="handleChangeType">
              <el-option-group v-for="group in [...fields]" :key="group.title" :label="group.title">
                <el-option
                  v-for="item in group.list" :key="item.type" :label="item.compLabel"
                  :value="item.type" />
              </el-option-group>
            </el-select>
          </el-form-item>
          <el-form-item label="组件名称">
            <el-input v-model="localData.fieldName" placeholder="请输入组件名称" />
          </el-form-item>
          <el-form-item label="绑定属性">
            <el-cascader
              :props="CascaderProps" :options="attrList" v-model="localData.prop" placeholder="请选择属性"
              filterable clearable :show-all-levels="false">
              <template #default="{ data: item }">
                <span>{{ `${item.entityDesc}(${item.entityName})` }}</span>
              </template>
            </el-cascader>
          </el-form-item>
          <el-form-item
            label="组件标题" v-if="
              localData.type != 'primary' &&
                localData.type != 'text' &&
                !localData.isDivider &&
                !localData.isTitle
            ">
            <el-input v-model="localData.label" id="entName" clearable @blur="checkLabelLength" placeholder="标题" />
          </el-form-item>
          <el-form-item label="占位文本">
            <el-input placeholder="请输入占位文本" v-model="localData.placeholder" />
          </el-form-item>
          <el-form-item label="标题宽度" v-if="!['group', 'title', 'primary', 'text'].includes(localData.type)">
            <el-input-number
              v-model="localData.labelWidth" :min="localData.label ? 60 : 0" :step="10"
              controls-position="right" placeholder="标签宽度" style="width: 100%" />
          </el-form-item>
          <el-form-item
            label="标签位置"
            v-if="!localData.subfield && localData.type != 'primary' && localData.type != 'text'">
            <el-radio-group v-model="localData.labelPosition">
              <el-radio-button label="上" value="top" />
              <el-radio-button label="左" value="left" />
              <el-radio-button label="右" value="right" />
            </el-radio-group>
          </el-form-item>
          <el-form-item label="组件宽度" v-if="!['group'].includes(localData.type)">
            <el-slider
              v-model="localData.span" :min="0" :max="24" :step="1" show-stops size="small"
              :format-tooltip="showSpanTooltip" />
          </el-form-item>
          <el-form-item label="整行占位">
            <el-switch v-model="localData.row" />
          </el-form-item>
          <el-form-item label="是否渲染">
            <el-switch v-model="localData.display" />
          </el-form-item>
          <el-form-item label="悬浮提示">
            <el-input v-model="localData.title" clearable placeholder="请输入悬浮提示" />
          </el-form-item>
          <el-form-item label="字段提示">
            <el-input v-model="localData.tip" clearable placeholder="字段提示" />
          </el-form-item>
          <el-form-item v-if="localData.tip && !['upload'].includes(localData.type)" label="字段提示位置" label-width="110px">
            <el-select v-model="localData.tipPlacement" placeholder="字段提示位置" clearable>
              <el-option label="上" value="top" />
              <el-option label="下" value="bottom" />
              <el-option label="左" value="left" />
              <el-option label="右" value="right" />
            </el-select>
          </el-form-item>
          <el-form-item label="标题提示">
            <el-input v-model="localData.labelTip" clearable placeholder="标题提示" />
          </el-form-item>
          <el-form-item
            v-if="localData.labelTip && !['upload'].includes(localData.type)" label="标题提示位置"
            label-width="110px">
            <el-select v-model="localData.labelTipPlacement" placeholder="标题提示位置" clearable>
              <el-option label="上" value="top" />
              <el-option label="下" value="bottom" />
              <el-option label="左" value="left" />
              <el-option label="右" value="right" />
            </el-select>
          </el-form-item>
          <el-form-item
            v-if="
              ![
                'color',
                'anvilDynamic',
                'group',
                'ueditor',
                'upload',
                'customButton',
                'anvilEsign',
                'imageUpload',
                'separator'
              ].includes(localData.type)
            " label="初始化值">
            <el-radio-group
              v-model="localData.defaultValueType" style="margin-bottom: 8px" size="default"
              @change="handleDefaultTypeChange">
              <el-radio-button
                v-for="(opt, idx) in getDefaultValueOptions(localData.type)" :key="idx"
                :label="opt.dictLabel" :value="opt.dictValue" />
            </el-radio-group>
            <div v-if="!localData.defaultValueType || localData.defaultValueType == '0'">
              <template v-if="defaultValues && defaultValues[localData.type]">
                <el-select v-model="localData.value" allow-create clearable filterable placeholder="默认值">
                  <el-option
                    v-for="item in defaultValues[localData.type]" :key="item.value" :label="item.label"
                    :value="item.value" />
                </el-select>
              </template>

              <template v-else-if="localData.type == 'vueQuillEditor'">
                <el-input v-model="localData.value" clearable placeholder="默认值">
                  <template #append>
                    <el-button icon="el-icon-edit" @click="showEditor" />
                  </template>
                </el-input>
              </template>
              <template v-else-if="localData.valueType">
                <el-input-number v-if="localData.valueType == 'number'" v-model="localData.value" placeholder="默认值" controls-position="right" />
                <el-input v-else v-model="localData.value" clearable placeholder="默认值" />
              </template>
            </div>
            <div v-else-if="localData.defaultValueType == '1'">
              <edit-formula v-model:data="localData" :formJson="formJson" />
            </div>
            <div v-else>
              <default-value-ajax :data="localData" @submit="setDefaultValueAjax" />
            </div>
          </el-form-item>

          <!--          <el-form-item v-if="data.type=='select'&&defaultValues[data.type][0].hide"-->
          <!--                        label="控制显隐">-->
          <!--            <template v-if="defaultValues && defaultValues[data.type]">-->
          <!--              <el-select v-model="data.hide"-->
          <!--                         multiple-->
          <!--                         filterable-->
          <!--                         allow-create-->
          <!--                         default-first-option-->
          <!--                         placeholder="选择字段名称">-->
          <!--                <el-option v-for="item in defaultValues[data.type]"-->
          <!--                           :key="item.value"-->
          <!--                           :label="item.label"-->
          <!--                           :value="item.value">-->
          <!--                </el-option>-->
          <!--              </el-select>-->
          <!--            </template>-->
          <!--          </el-form-item>-->

          <!--          <el-form-item label="控制显隐" v-if="data.type=='select'||data.type=='radio'">-->
          <!--            <el-switch v-model="data.hide"></el-switch>-->
          <!--          </el-form-item>-->

          <!-- <el-form-item label="详情模式">
            <el-switch v-model="data.detail"></el-switch>
          </el-form-item> -->

          <!-- 只读模式目前和禁用模式没有做区分，暂时禁用 -->

          <el-form-item label="是否只读">
            <el-switch v-model="localData.readonly"></el-switch>
          </el-form-item>
          <el-form-item label="是否禁用">
            <el-switch v-model="localData.disabled" />
          </el-form-item>
          <el-form-item label="是否必填">
            <el-switch v-model="localData.isRequired" active-value="Y" inactive-value="N" />
            <el-input
              type="textarea" v-if="localData.isRequired == 'Y'" v-model.lazy="localData.requiredFunc"
              placeholder="自定义必填函数"></el-input>
            <el-input v-if="localData.isRequired == 'Y'" v-model.lazy="localData.pattern" placeholder="正则表达式" />
          </el-form-item>
          <el-form-item label="自定义样式">
            <el-select v-model="localData.classNames" multiple clearable>
              <el-option v-for="(item,index) in classNames" :label="item.className" :value="item.className" :key="index" />
            </el-select>
          </el-form-item>
          <!-- <el-form-item v-if="localData.parentName" label="单条数据内不许重复" label-width="140">
            <el-switch v-model="localData.uniqe" @change="uniqeTipSet" />
            <div v-if="localData.uniqe">
              <span class="tips-text">自定义提示内容</span>
              <el-input v-model="localData.uniqeTip" />
            </div>
          </el-form-item> -->
          <el-form-item v-if="localData.parentName" label="列宽度">
            <el-input-number v-model="localData.columnWidth" controls-position="right" placeholder="列宽度" />
          </el-form-item>
          <el-form-item v-if="localData.parentName" label="列最小宽度">
            <el-input-number v-model="localData.columnMinWidth" controls-position="right" placeholder="列最小宽度" />
          </el-form-item>
          <el-form-item v-if="localData.parentName" label="列固定">
            <el-radio-group v-model="localData.fixed">
              <el-radio-button label="无" value="-" />
              <el-radio-button label="左侧" value="left" />
              <el-radio-button label="右侧" value="right" />
            </el-radio-group>
          </el-form-item>
          <el-form-item v-if="localData.parentName" label="列编辑">
            <el-switch v-model="localData.columnEditable" />
          </el-form-item>
          <el-form-item v-if="localData.parentName" label="显示气泡">
            <el-switch v-model="localData.showTooltip" />
          </el-form-item>
        </el-collapse-item>
        <el-collapse-item name="2" title="组件专有属性">
          <component
            :is="getComponent" v-model:data="localData" :formJson="formJson" :default-values="defaultValues"
            :notSavedOptions="notSavedOptions" :formModelDataFromDesign="formModelDataFromDesign"
            :attrList="attrList" />
        </el-collapse-item>
        <el-collapse-item name="3" title="子页面属性" v-if="localData.type == 'anvilDynamic' || localData.type == 'anvilVforTable'">
          <form-config style="padding: 0 0 0 24px" :data="localData.children" :isDynamic="true" />
        </el-collapse-item>
        <el-collapse-item name="4" title="事件属性" v-if="curEvents">
          <config-events v-model:data="localData" :curEvents="curEvents" :formJson="formJson"></config-events>
        </el-collapse-item>
      </el-collapse>
    </el-form>
    <editor-dialog
      v-if="showEditorDialog" v-model:data="showEditorDialog" :defaultValue="localData.value"
      @submit="setEditorDefault" append-to-body />
  </div>
</template>

<script>
// import fields from './fieldsConfig.js'
import styleSelect from './styleSelect.js'
import { getPinyin } from '@/api/common'
import { getModelEntityTreeByids } from '@uni/api/uni/entity/info'
import FormConfig from './FormConfig.vue'
import editorDialog from './config/extend/quillEditor/editorDialog.vue'
import defaultValueAjax from './components/defaultValueAjax.vue'
import editFormula from './components/editFormula.vue'
// import customFuncConfig from './components/customFuncConfig.vue'
import { generateValidUuid } from '@code/components/anvil-code-low-common/utils/common-methods'
import EventsMap from '@code/components/anvil-code-low-common/components/EventsMap';

const dateArr = [
  'year',
  'month',
  'week',
  'date',
  'datetime',
  'time',
  'daterange',
  'timerange',
  'datetimerange',
  'dates'
]

const defaultValueOptions = [
  {
    dictLabel: '自定义',
    dictValue: '0'
  },
  {
    dictLabel: '公式',
    dictValue: '1'
  },
  {
    dictLabel: '接口',
    dictValue: '2'
  }
]

export default {
  name: 'WidgetConfig',
  components: {
    FormConfig,
    editorDialog,
    defaultValueAjax,
    editFormula,
  },
  props: {
    data: {
      type: Object,
      default: () => { }
    },
    defaultValues: {
      type: Object,
      default: () => { }
    },
    notSavedOptions: {
      type: Array,
      default: () => []
    },
    inputSelect: {
      type: Array,
      default: () => []
    },
    fields: {
      type: Array,
      default: () => []
    },
    formModelDataFromDesign: {
      type: Object,
      default: () => { }
    },
    formJson: {
      type: Object,
      default: () => { }
    },
    attrList: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      defaultValueOptions,
      positionOption: [
        {
          value: 'horizontal',
          label: '水平'
        },
        {
          value: 'vertical',
          label: '垂直'
        }
      ],
      titleOption: [
        {
          value: 'left',
          label: '居左'
        },
        {
          value: 'right',
          label: '居右'
        },
        {
          value: 'center',
          label: '居中'
        }
      ],
      restaurants: [],
      // fields,
      styleSelect,
      associationName: '',
      associationKey: '',
      selectFormDialog: false,
      collapse: ['1'],
      validator: {
        type: null,
        required: null,
        pattern: null,
        length: null
      },
      showEditorDialog: false,
      localData: {},
      // attrList: [],
      CascaderProps: {
        value: 'entityName',
        label: 'entityDescName',
        children: 'childList',
        emitPath: false
      }
    }
  },
  computed: {
    // 当前组件支持的事件列表
    curEvents() {
      return EventsMap[this.localData.type]
    },
    // 获取样式类名
    classNames(){
      return this.formJson.classes ? this.formJson.classes : []
    },
    getComponent() {
      const unRenderConfigs = [
        'user',
        'users',
        'company',
        'companys',
        'post',
        'posts',
        'role',
        'roles',
        'dept',
        'depts',
        'varchar'
      ]
      const prefix = 'config-'
      const { type, component, widget } = this.localData

      // 初始化属性操作
      this.initAttrs(type)

      // 暂时不渲染属性配置的组件,解决报错
      if (unRenderConfigs.indexOf(type) > -1) {
        return 'div'
      }
      // console.log('馒头片',type,component,this.data);

      if ((!type || component) && type != 'ueditor' && type != 'primary') return prefix + 'custom'
      let result = 'input'
      if (
        [
          undefined,
          'input',
          'password',
          'url',
          'counter',
          'user',
          'users',
          'company',
          'companys',
          'post',
          'posts',
          'role',
          'roles',
          'dept',
          'depts'
        ].includes(type)
      )
        result = 'input'
      else if (dateArr.includes(type)) result = 'date'
      else if (['array', 'img'].includes(type)) result = 'array'
      else if (['tree', 'cascader'].includes(type)) result = 'tree'
      // else if ([ 'select', 'selects'].includes(type)) result = 'select'
      else if (['primary'].includes(type)) result = 'button'
      else result = type
      // console.log(prefix + result);
      return widget ? result + 'Config' : prefix + result
    },
  },
  watch: {
    data: {
      handler(newVal) {
        if (newVal) {
          this.localData = newVal
        }
      },
      deep: true,
      immediate: true
    },
    localData: {
      handler(newVal) {
        this.$emit('update:data', newVal)
      },
      deep: true
    },
    'localData.isRequired'(val) {
      if (val == 'Y') {
        this.validator.required = {
          required: true,
          message: `${this.localData.label}必须填写`
        }
      } else {
        this.validator.required = null
      }
      this.generateRule()
    },
    'localData.pattern'(val) {
      if (val)
        this.validator.pattern = {
          pattern: new RegExp(val),
          message: `${this.localData.label}格式不匹配`
        }
      else this.validator.pattern = null
      this.generateRule()
    },
    inputSelect: {
      handler(newVal) {
        this.restaurants = newVal
      },
      deep: true
    }
  },
  created() {
    this.$nextTick(() => {
      console.log('formModelDataFromDesign', this.formModelDataFromDesign)
    })

    // this.$set(this.data,'isRequired',"Y")
  },
  mounted() {
    this.restaurants = this.inputSelect
    // this.getAttrsByEntity()
  },
  unmounted() {
    // this.$EventBus.$off("selectedKey");
  },
  methods: {
    chineseFormat: function (e, t, n, i, o, isDynamic) {
      console.log('chineseFormat', e, t, n, i, o, isDynamic)
      // eslint-disable-next-line @typescript-eslint/no-this-alias
      var a = this
      // 要等待s挂载完成
      this.$nextTick(() => {
        var s = document.getElementById(e),
          l = null
        null === s ||
          !o ||
          (l && clearTimeout(l),
            (l = setTimeout(function () {
              // isDynamic为false或者不传，接口第二个字段用于返回带下划线的拼音
              if (!isDynamic) {
                if (t.isAllowEdit != 'N') {
                  getPinyin(o, 'column').then(function (res) {
                    t.prop = res.data
                  })
                }
              }
              // isDynamic为true，用来返回子表单生成的prop
              else {
                const { formModelCode } = a.formModelDataFromDesign
                if (t.isAllowEdit != 'N') {
                  getPinyin(o, 'prop', formModelCode).then(function (res) {
                    t.prop = res.data
                  })
                }

                getPinyin(o, 'column').then(function (res) {
                  t.formKey = res.data
                })
              }
            }, 500)))
      })
    },
    selectChangeParent(index) {
      this.localData.params.borderStyle = this.styleSelect[index].borderStyle
      this.localData.params.complex = this.styleSelect[index].complex
      this.localData.params.fontPosition = this.styleSelect[index].fontPosition
      // this.data.params.slotName = this.styleSelect[index].slotName?this.styleSelect[index].slotName:''
      this.localData.params.class1 = this.styleSelect[index].class1
      this.localData.params.class2 = this.styleSelect[index].class2
      this.localData.params.class3 = this.styleSelect[index].class3
      this.localData.params.class4 = this.styleSelect[index].class4
      this.localData.params.class5 = this.styleSelect[index].class5
      this.localData.params.class6 = this.styleSelect[index].class6
      this.localData.params.class7 = this.styleSelect[index].class7
      this.localData.params.class8 = this.styleSelect[index].class8
    },
    querySearch(queryString, cb) {
      var restaurants = this.restaurants
      var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants
      // 调用 callback 返回建议列表的数据
      cb(results)
    },
    createFilter(queryString) {
      return (restaurant) => {
        return restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
      }
    },
    handleSelect(item) {
      this.localData.prop = item.value.split('(')[1].split(')')[0]
      this.localData.label = item.label
    },
    handleChangeType(type) {
      if (!type) return
      const totalFields = [...this.fields]
      const field = totalFields.find((f) => f.list.find((l) => l.type == type))
      const { list } = field
      const config = list.find((item) => item.type === type)
      if (!config) return

      for (let key in config) {
        // 切换组件类型时名称不随之切换
        if (key !== 'label') {
          this.localData[key] = config[key]
          // this.$set(this.localData, key, config[key])
        }
      }

      for (let key in this.localData) {
        if (!Object.prototype.hasOwnProperty.call(config, key)) {
          delete this.localData[key]
        }
      }
      // for (let key in config) {
      //   if (config && Object.prototype.hasOwnProperty.call(config, key) && !['icon', 'label', 'span'].includes(key)) this.$set(this.data,key,config[key])
      // }
    },
    generateRule() {
      const rules = []
      Object.keys(this.validator).forEach((key) => {
        if (this.validator[key]) rules.push(this.validator[key])
      })
      if (rules.length == 0) delete this.localData.rules
      else this.localData.rules = rules
    },
    // 校验标题名称长度
    checkLabelLength() {
      if (this.localData.label) {
        const len = this.localData.label.length
        if (len > 20) {
          this.$message.error('标题名称长度不能超过20！')
          this.localData.label = this.localData.label.substring(0, 20)
          this.localData.prop = this.localData.prop.substring(0, 20)
        }
      }
    },
    checkPropLength() {
      if (this.localData.prop) {
        const len = this.localData.prop.length
        if (len > 20) {
          this.$message.error('属性值长度不能超过20！')
          this.localData.prop = this.localData.prop.substring(0, 20)
        }
      }
    },
    uniqeTipSet(value) {
      const defaultTip = '此项内容已存在，不允许重复提交'
      if (value) {
        this.localData.uniqeTip = defaultTip
        // this.$set(this.localData, 'uniqeTip', defaultTip)
      }
    },
    showEditor() {
      this.showEditorDialog = true
    },
    // 设置富文本的默认值
    setEditorDefault(html) {
      console.log('html', html)
      this.localData.value = html
      // this.$set(this.localData, 'value', html)
    },
    setDefaultValueAjax(data) {
      const { defaultValueAjax } = data
      this.localData.defaultValueAjax = defaultValueAjax
      // this.$set(this.localData, 'defaultValueAjax', defaultValueAjax)
    },
    handleDefaultTypeChange(value) {
      if (value !== '0') {
        this.localData.value = undefined
        // this.$set(this.localData, 'value', undefined)
      }

      if (value !== '1') {
        this.localData.formula = undefined
        this.localData.formulaTag = undefined
        // this.$set(this.localData, 'formula', undefined)
        // this.$set(this.localData, 'formulaTag', undefined)
      }

      if (value !== '2') {
        this.localData.defaultValueAjax = undefined
        // this.$set(this.localData, 'defaultValueAjax', undefined)
      }
    },
    // 根据组件类型返回不同的默认值设置类型
    getDefaultValueOptions(type) {
      return this.defaultValueOptions.filter((item) => {
        if (item.dictValue == '1') {
          return ['input', 'number', 'textarea'].indexOf(type) > -1
        } else {
          return true
        }
      })
    },
    genProp(type) {
      // 表单驱动模型的组件生成特定prop
      // 如果为entity字段，则初始化的时候不进行prop赋值
      // 现在逻辑为只有完全新增的组件会进行一次prop赋值，其他情况都不会
      if (!this.localData.formEntityName && !this.localData.prop) {
        this.localData.prop = generateValidUuid()
      }
    },
    // 生成32位uuid
    genCompUuid() {
      this.localData.uuid = this.localData.prop
    },
    // 生成字段名称
    genFieldName() {
      this.localData.fieldName = this.localData.label
    },
    showSpanTooltip(v) {
      if (v == 0) {
        return '不显示'
      } else if (v == 24) {
        return '整行'
      }
    },
    // 初始化属性操作
    initAttrs(type) {
      this.genProp(type)
      // 设置uuid
      if (!this.localData.uuid) {
        this.genCompUuid()
      }
      if (!this.localData.fieldName) {
        this.genFieldName()
      }
      if(!this.localData.classNames){
        this.localData.classNames = []
      }
    }
  }
}
</script>
<style lang="scss" scoped>
@import './styles/selectStyle.scss';

.widget-config .el-form-item__label {
  padding: 0;
}

.flex {
  display: flex;
}

.tips-text {
  color: #838892;
  font-size: 12px;
}

:deep(.el-form-item--default) {
  margin-bottom: 8px;
}
</style>
